package com.dhecp.project.storage.service.impl;


import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dhecp.core.utils.RedisUtil;
import com.dhecp.core.utils.forest.FroestHttPUtils;
import com.dhecp.project.api.util.ApiConfig;
import com.dhecp.project.finance.domain.AccountCountForCompany;
import com.dhecp.project.finance.domain.AccountDetailedForCompany;
import com.dhecp.project.finance.mapper.AccountCountForCompanyMapper;
import com.dhecp.project.finance.mapper.AccountDetailedForCompanyMapper;
import com.dhecp.project.storage.domain.*;
import com.dhecp.project.storage.enums.HwStorageEnum;
import com.dhecp.project.storage.mapper.*;
import com.dhecp.project.system.domain.SysAccountBandDept;
import com.dhecp.project.system.domain.SysDepotInfo;
import com.dhecp.project.system.mapper.SysAccountBandDeptMapper;
import com.dhecp.project.system.mapper.SysDepotInfoMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.common.utils.MessageUtils;
import com.dhecp.common.utils.RandomValueUtils;
import com.dhecp.core.constant.DataFiltering;
import com.dhecp.core.utils.PageUtils;
import com.dhecp.project.business.domain.LogisticsMmodeGrads;
import com.dhecp.project.business.domain.LogsticsPattern;
import com.dhecp.project.business.domain.LogsticsPatternDetails;
import com.dhecp.project.business.mapper.LogsticsPatternDetailsMapper;
import com.dhecp.project.business.mapper.LogsticsPatternMapper;
import com.dhecp.project.common.service.impl.BaseModuleServiceImpl;
import com.dhecp.project.logstics.mapper.LogsticsMmodeGradsMapper;
import com.dhecp.project.storage.enums.DeliveryBoxEnum;
import com.dhecp.project.storage.enums.DeliveryLogisticsEnum;
import com.dhecp.project.storage.service.DeliveryLogisticsService;
import com.dhecp.project.system.service.SysDictionaryForFieldService;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

/**
 * 查询海外发货申请单 服务层
 */
@Service
public class DeliveryLogisticsServicelmpl extends BaseModuleServiceImpl implements DeliveryLogisticsService {

	private static Logger logger = LoggerFactory.getLogger(DeliveryLogisticsServicelmpl.class);

    @Autowired
    private DeliveryLogisticsMapper deliveryLogisticsMapper;
    @Autowired
    private DeliveryBoxMapper deliveryBoxMapper;
    @Autowired
    private DeliveryBoxDetailMapper deliveryBoxDetailMapper;
    @Autowired
    private DeliveryRequestMapper deliveryRequestMapper;
    @Autowired
    private GoodsAllocationMapper goodsAllocationMapper;

    @Autowired
    private DeliveryRequestDetailMapper deliveryRequestDetailMapper;

    @Autowired
    private LogsticsMmodeGradsMapper logsticsMmodeGradsMapper;
    @Autowired
    private LogsticsPatternMapper logsticsPatternMapper;
    @Autowired
    private LogsticsPatternDetailsMapper logsticsPatternDetailsMapper;
    @Autowired
    private StockControlMapper stockControlMapper;
    @Autowired
    private StockControlRunningMapper stockControlRunningMapper;

    @Autowired
    private SysDictionaryForFieldService dictionaryForFieldService;

    @Autowired
	private SysAccountBandDeptMapper sysAccountBandDeptMapper;

	@Autowired
	private AccountCountForCompanyMapper accountCountForCompanyMapper;

	@Autowired
	private AccountDetailedForCompanyMapper businessMapper;

	@Autowired
	private SysDepotInfoMapper sysDepotInfoMapper;

	@Autowired
	private DeliveryLogisticsDetailMapper deliveryLogisticsDetailMapper;


	@Autowired
	private RedisUtil redisUtil;

	@Autowired
	private GaugeMaintenanceMapper gaugeMaintenanceMapper;

	@Autowired
	private HwStorageMapper hwStorageMapper;

    /**
     * 查询查询海外发货申请单
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public List<DeliveryLogistics> queryList(Map<String, Object> params) throws Exception {
    	
        params.put(DataFiltering.TABLE_ALIAS, "t1");	//查询表别名
        params.put(DataFiltering.DATA_WHERE, dictionaryForFieldService.getWhereStr(params));	//常规查询条件SQL语句
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));	//数据权限查询条件SQL语句

        if (params.get("field") == null || params.get("field") == ""){
            String orderBy = "t1.createTime DESC";
            PageUtils.startPageOrder(orderBy);
        }else{
            PageUtils.startPage();
        }
        return deliveryLogisticsMapper.select(params);
    }

    /**
     * 查询海外发货申请单-明细
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public List<DeliveryBoxDetail> querySonListByBid(Map<String, Object> params) throws Exception {
        params.put(DataFiltering.TABLE_ALIAS, "t1");	//查询表别名
        String orderBy = "t1.createTime DESC";
        PageUtils.startPageOrder(orderBy);
        return deliveryBoxDetailMapper.select(params);
    }
    /**
     * 查询查询海外发货申请单
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public DeliveryLogistics queryFirstRecord(Map<String, Object> params) throws Exception {

        params.put(DataFiltering.TABLE_ALIAS, "t1");    //查询表别名
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));    //数据权限查询条件SQL语句
        return deliveryLogisticsMapper.selectFirstRecordByNid(params);
    }

	@Override
	public DeliveryLogistics queryByBid(String bid) {
		return deliveryLogisticsMapper.findByBid(bid);
	}

	@Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public AjaxResult saveData(Map<String, Object> params) throws Exception {
		
		String bid = params.get("bid").toString();
		if (bid == null || bid.length() == 0) {
			return AjaxResult.error("单号为空，无法操作！");
		}
		
		DeliveryLogistics deliveryLogisticsOld = deliveryLogisticsMapper.findByBid(bid);
		if (!deliveryLogisticsOld.getStateName().equals(DeliveryLogisticsEnum.StateName.INIT.value)) {
			return AjaxResult.error("非制单环节，无法操作！");
		}
		
		// 验证物流名称编码
		String codeLogsticsPattern = params.get("codeLogsticsPattern").toString();
		if (codeLogsticsPattern == null || codeLogsticsPattern.length() == 0) {
			return AjaxResult.error("请选择物流名称！");
		}
		
		LogsticsPattern logsticsPattern = logsticsPatternMapper.queryFirstByCode(codeLogsticsPattern);

		DeliveryLogistics deliveryLogistics = JSON.parseObject(JSON.toJSONString(params), DeliveryLogistics.class);
//		System.out.println(JSON.toJSONString(deliveryLogistics));
		deliveryLogistics.setCodeLogsticsServer(logsticsPattern.getNameLogsticsServer());
		deliveryLogistics.setCodeCompany(logsticsPattern.getCodeCompany());
		deliveryLogistics.setNameCompany(logsticsPattern.getNameCompany());
		if (deliveryLogisticsOld.getFreeChannel().contains(logsticsPattern.getCodeCompany())){
			deliveryLogistics.setWarehousingCharge(BigDecimal.ZERO);
		}
		deliveryLogisticsMapper.update(deliveryLogistics);
		
//		// 保存明细数据
//		String detailArr = params.get("detailArr").toString();
//		JSONArray detailJA = JSON.parseArray(detailArr);
//		for (int i = 0; i < detailJA.size(); i++) {
//			JSONObject detailJO = detailJA.getJSONObject(i);
//			DeliveryLogisticsDetail deliveryLogisticsDetail = JSON.parseObject(detailJO.toJSONString(), DeliveryLogisticsDetail.class);
//			deliveryLogisticsDetailMapper.update(deliveryLogisticsDetail);
//		}
		
		return AjaxResult.success("操作成功");
	}
	
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult updateState(String bid) throws Exception {
    	
    	DeliveryLogistics deliveryLogistics = deliveryLogisticsMapper.findByBid(bid);
    	if (!deliveryLogistics.getStateName().equals(DeliveryLogisticsEnum.StateName.INIT.value)) {
			return AjaxResult.error("该单据非待审核状态，无法重复操作");
		} else if (deliveryLogistics.getNameLogsticsPattern() == null || deliveryLogistics.getNameLogsticsPattern().length() == 0) {
			return AjaxResult.error("物流名称尚未填写");
		}

        
        // 添加库存相关-调出方库存总数量变更
    	List<DeliveryRequestDetail> listDeliveryRequestDetail = deliveryRequestDetailMapper.queryFirstByPBid(deliveryLogistics.getBidRequest());
        // 商品-总数量MAP，商品-商品名称MAP，用于待入库区
    	Map<String, Integer> PRODUCTCODE_NUMALL_MAP = new HashMap<String, Integer>();
    	Map<String, String> PRODUCTCODE_NAME_MAP = new HashMap<String, String>();
    	for(DeliveryRequestDetail deliveryRequestDetail : listDeliveryRequestDetail) {
    		// 解冻出库
    		StockControl stockControlOut = stockControlMapper.findByGuid(deliveryRequestDetail.getGuidKc());
    		{
    			stockControlOut.setProductNumAll(stockControlOut.getProductNumAll() - deliveryRequestDetail.getNumDeliver());
    			stockControlMapper.update(stockControlOut);
    		}
    		
    		// 商品数量和商品名称MAP更新
    		String productCode = deliveryRequestDetail.getCommodityCode();
    		Integer numAll = PRODUCTCODE_NUMALL_MAP.containsKey(productCode) ? PRODUCTCODE_NUMALL_MAP.get(productCode) + deliveryRequestDetail.getNumDeliver() : deliveryRequestDetail.getNumDeliver();
			PRODUCTCODE_NUMALL_MAP.put(productCode, numAll);
			if (!PRODUCTCODE_NAME_MAP.containsKey(productCode)) {
				PRODUCTCODE_NAME_MAP.put(productCode, deliveryRequestDetail.getName());
			}
        }
        
        // 添加库存相关-待入库
    	DeliveryRequest deliveryRequest = deliveryRequestMapper.findByBid(deliveryLogistics.getBidRequest());
    	Date now = new Date();
        for(Entry<String, Integer> e : PRODUCTCODE_NUMALL_MAP.entrySet()) {

        	String productCode = e.getKey();
        	Integer productNumAll = e.getValue();
            // 添加库存-入库
    		StockControl stockControlIn = new StockControl();
    		{
    			stockControlIn.setGuid(RandomValueUtils.getGUID());
    			stockControlIn.setRkBid(deliveryLogistics.getBid());
    			stockControlIn.setRkGuid(deliveryLogistics.getGuid());
    			stockControlIn.setProductCode(productCode);
    			stockControlIn.setProductName(PRODUCTCODE_NAME_MAP.get(productCode));
    			stockControlIn.setvHw("待入库");
    			stockControlIn.setvKq("待入库区");
    			stockControlIn.setgDepot(deliveryLogistics.getDestHouseAddress());
    			stockControlIn.setvGsBm(deliveryLogistics.getvGsBm());
    			stockControlIn.setvGsMc(deliveryRequest.getvGsMc());
    			stockControlIn.setvGsJc(deliveryLogistics.getvGsJc());
    			stockControlIn.setProductNum(0);
    			stockControlIn.setProductNumAll(productNumAll);
    			stockControlIn.setdRkSj(now);
    			stockControlIn.setCreateTime(now);
    			stockControlIn.setIsParent(productCode.contains("-") ? "0" : "1");
    			stockControlMapper.insert(stockControlIn);
    		}
    		
    		// 添加库存流水-入库
    		{
    		StockControlRunning stockControlRunning = new StockControlRunning();
        		stockControlRunning.setGuid(RandomValueUtils.getGUID());
        		stockControlRunning.setGuidStockControl(stockControlIn.getGuid());
        		stockControlRunning.setBidRelative(bid);
        		stockControlRunning.setLocationHw(stockControlIn.getvHw());
        		stockControlRunning.setProductCode(stockControlIn.getProductCode());
        		stockControlRunning.setvGsBm(stockControlIn.getvGsBm());
        		stockControlRunning.setProductNumChange(productNumAll);
        		stockControlRunning.setProductNumLeft(stockControlIn.getProductNum());
        		stockControlRunning.setCreateTime(now);
        		
        		stockControlRunning.setRemark("海外仓入库" + bid);
        		stockControlRunningMapper.insert(stockControlRunning);
    		}
    		
        }
        //从逸思精品账户（公司账户）向物流部账户（部门账户）进行划拨。
		SysAccountBandDept wlb = sysAccountBandDeptMapper.findByAccountId("WLB");
		if (wlb == null) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return AjaxResult.error("物流部(部门账户)不存在,请核实后再操作!");
		}
		// 物流公司
		AccountCountForCompany logisticsAccount = accountCountForCompanyMapper.queryFirstByVGsBm(wlb.getvGsBm());
		if (logisticsAccount == null) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return AjaxResult.error("物流公司实时资金不存在,请核实后再操作!");
		}
//                     精品公司
		AccountCountForCompany jpAccount = accountCountForCompanyMapper.queryFirstByVGsBm(deliveryLogistics.getvGsBm());
		if (jpAccount == null) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return AjaxResult.error("逸思精品实时资金不存在,请核实后再操作!");
		}
		List<AccountDetailedForCompany> accountList =new ArrayList<>();
		AccountDetailedForCompany account = new AccountDetailedForCompany();
		account.setGuid(RandomValueUtils.getGUID());
		account.setvGsBm(jpAccount.getvGsBm());
		account.setvGsMc(jpAccount.getvGsMc());
		account.setvGsJc(jpAccount.getvGsJc());
		account.setvGsBmP(logisticsAccount.getvGsBm());
		account.setvGsMcP(logisticsAccount.getvGsMc());
		account.setvGsJcP(logisticsAccount.getvGsJc());
		account.setvJyLx("物流服务→头程运费");
		account.setfJe(-Double.valueOf(String.valueOf(deliveryLogistics.getPriceTotal())));
		account.setdJySj(deliveryLogistics.getCreateTime());
		account.setdShSj(new Date());
		account.setvBz("头程物流费,"+ "海外发货申请单:"+deliveryLogistics.getBidRequest()+",物流方式名称:"+deliveryLogistics.getNameLogsticsWay());
		account.setCreateTime(new Date());
		accountList.add(account);

		//资金流水(物流部 -运营公司头程物流费)
		AccountDetailedForCompany account1 = new AccountDetailedForCompany();
		account1.setGuid(RandomValueUtils.getGUID());
		account1.setvGsBm(logisticsAccount.getvGsBm());
		account1.setvGsMc(logisticsAccount.getvGsMc());
		account1.setvGsJc(logisticsAccount.getvGsJc());
		account1.setvGsBmP(jpAccount.getvGsBm());
		account1.setvGsMcP(jpAccount.getvGsMc());
		account1.setvGsJcP(jpAccount.getvGsJc());
		account1.setvJyLx("物流服务→头程运费");
		account1.setfJe(Double.valueOf(String.valueOf(deliveryLogistics.getPriceTotal())));
		account1.setdJySj(deliveryLogistics.getCreateTime());
		account1.setdShSj(new Date());
		account1.setvBz("头程物流费,"+"海外发货申请单:"+deliveryLogistics.getBidRequest()+",物流方式名称:"+deliveryLogistics.getNameLogsticsWay());
		account1.setCreateTime(new Date());
		accountList.add(account1);

		if (accountList.size() != 0){
			businessMapper.insertBatchNew(accountList);
		}

		//判断是否需要登录
		if (redisUtil.get("FROESTLOGIN") == null){
			JSONObject jsonObject = FroestHttPUtils.froestLogin();
			if (jsonObject.get("code") != null){
				if (!jsonObject.get("code").equals("200")){
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return AjaxResult.error("连接大森林海外仓API失败,请联系管理员处理!");
				}
			}
			redisUtil.setEx("FROESTLOGIN", jsonObject.get("access_token").toString(),Long.valueOf(jsonObject.get("expires_in").toString()),TimeUnit.SECONDS);
			redisUtil.setEx("FROESTLOGINCode", jsonObject.get("customerCode").toString(),Long.valueOf(jsonObject.get("expires_in").toString()),TimeUnit.SECONDS);
		}

		//查询仓库编码
		SysDepotInfo sysDepotInfo = sysDepotInfoMapper.findDepotInfoByDepotName(deliveryLogistics.getDestHouseAddress());
		if (sysDepotInfo == null){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return AjaxResult.error("仓库信息不存在,请核实后再操作!");
		}

		List<HwGodwnOrder> hwGodwnOrderList = new ArrayList<>();
		HwGodwnOrder hwGodwnOrder = new HwGodwnOrder();
		List<HwSkuList> hwSkuListList = new ArrayList<>();
		//查询发货物流明细
		List<DeliveryLogisticsDetail> deliveryLogisticsDetails = deliveryLogisticsDetailMapper.listByBidLogistics(deliveryLogistics.getBid());
		for(DeliveryLogisticsDetail deliveryLogisticsDetail : deliveryLogisticsDetails) {
			HwSkuList hwSkuList = new HwSkuList();
			hwSkuList.setDeliveryChannel("1");
			hwSkuList.setDeliveryNum(deliveryLogisticsDetail.getProductNum());
			hwSkuList.setNo(deliveryLogisticsDetail.getBoxNo());
			hwSkuList.setTrackingNumber("1");
			hwSkuList.setSku(redisUtil.get("FROESTLOGINCode") + "-" +deliveryLogisticsDetail.getProductCode());
			hwSkuListList.add(hwSkuList);
		}
		hwGodwnOrder.setSkuList(hwSkuListList);
		hwGodwnOrder.setWarehouseCode(sysDepotInfo.getDepotId());
		String value = deliveryLogistics.getTimeArrivePredict() + " 00:00:00";
		hwGodwnOrder.setExpectedTimeOfArrival(value);
		hwGodwnOrder.setRemark(deliveryLogistics.getvBz());
		hwGodwnOrderList.add(hwGodwnOrder);

		//创建入库单
		JSONObject jsonObject = FroestHttPUtils.froestApiRequest(JSON.toJSONString(hwGodwnOrderList),redisUtil.get("FROESTLOGIN"),
				ApiConfig.getWmsUrl()+"/interface/wmsOrderApi/createGodwnEntryOrder");
		JSONArray  jsonArray = null;
		if (jsonObject.get("code") != null){
			if (!jsonObject.get("code").equals(200)){
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				logger.error("大森林海外仓API创建入库单失败，错误为：" + jsonObject.get("message"));
				return AjaxResult.error("大森林海外仓API创建入库单失败,请联系管理员处理!");
			}
		}
		jsonArray = JSONArray.parseArray(jsonObject.get("result").toString());

		//入库单审核
		jsonObject = FroestHttPUtils.froestApiRequest("",redisUtil.get("FROESTLOGIN"),
				ApiConfig.getWmsUrl()+"/interface/wmsOrderApi/checkGodwnEntryOrder?godownEntryNo="+String.valueOf(jsonArray.get(0)));
		if (jsonObject.get("code") != null){
			if (!jsonObject.get("code").equals(200)){
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				logger.error("大森林海外仓API入库单审核失败，错误为：" + jsonObject.get("message"));
				return AjaxResult.error("大森林海外仓API入库单审核失败,请联系管理员处理!");
			}
		}

		deliveryLogisticsMapper.updateStateAndOverseasStockInNo(bid,   DeliveryLogisticsEnum.StateName.SUCCESS.value, String.valueOf(jsonArray.get(0)));

		return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }
	
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult refuse(String bid) throws Exception {
    	
    	DeliveryLogistics deliveryLogistics = deliveryLogisticsMapper.findByBid(bid);
    	if (!deliveryLogistics.getStateName().equals(DeliveryLogisticsEnum.StateName.INIT.value)) {
			return AjaxResult.error("该单据非待审核状态，无法重复操作");
		}
    	
    	
    	// 删除装箱单
    	deliveryLogisticsMapper.deleteByBid(bid);
    	
    	// 更新装箱单状态
    	deliveryBoxMapper.updateState(deliveryLogistics.getBidBox(), DeliveryBoxEnum.StateName.INIT.value);
        
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }
	
    @Override
    public AjaxResult getPriceInfo(String codeLogsticsPattern, BigDecimal weight, String bidBox) {
    	
    	if (codeLogsticsPattern == null || codeLogsticsPattern.length() == 0) {
			return AjaxResult.error("请先选择物流名称");
		}
    	
    	LogsticsPattern logisticsPattern = logsticsPatternMapper.queryFirstByCode(codeLogsticsPattern);
    	LogisticsMmodeGrads logisticsMmodeGrads = logsticsMmodeGradsMapper.findByWeightAndGuid(logisticsPattern.getGuid(), weight);
    	

    	List<DeliveryBoxDetail> listDeliveryBoxDetail = deliveryBoxDetailMapper.listByBidBox(bidBox);
    	// 品名拼接，用,隔开
    	String materialNameCns = "";
    	for(DeliveryBoxDetail deliveryBoxDetail : listDeliveryBoxDetail) {
    		materialNameCns = materialNameCns + deliveryBoxDetail.getProductMaterialCn() + ",";
    	}
    	materialNameCns = materialNameCns.length() > 0 ? materialNameCns.substring(0, materialNameCns.length() - 1) : "";
    	materialNameCns = "'" + materialNameCns.replace(",", "','") + "'";
    	
    	LogsticsPatternDetails logsticsPatternDetails = logsticsPatternDetailsMapper.findMaxCostByNameCns(materialNameCns, codeLogsticsPattern);
    	if (logsticsPatternDetails == null) {
			return AjaxResult.error("找不到该物流名称的材质");
		}
    	if (logisticsMmodeGrads == null) {
			return AjaxResult.error("找不到对应的计重梯度单价");
		}

		BigDecimal pricePerKgSingle = logisticsMmodeGrads.getKg(); // 计重单价
		BigDecimal priceProNameExtraSingle = logsticsPatternDetails.getMaterialCost(); // 附加材质单价
		String nameMaterialMax = logsticsPatternDetails.getMaterialName();
    	Map<String, Object> result = new HashMap<String, Object>();
    	result.put("pricePerKgSingle", pricePerKgSingle);
    	result.put("priceProNameExtraSingle", priceProNameExtraSingle);
    	result.put("nameMaterialMax", nameMaterialMax);
        
        return AjaxResult.success(result);
    }
	
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult stockIn(String bid, String vHwTo) throws Exception {
    	
    	if (vHwTo == null || vHwTo.length() == 0) {
			return AjaxResult.error("货位不能为空");
		}
    	
    	DeliveryLogistics deliveryLogistics = deliveryLogisticsMapper.findByBid(bid);
    	GoodsAllocation goodsAllocation = goodsAllocationMapper.findByGoodsAllocation(vHwTo, deliveryLogistics.getDestHouseAddress());
    	if (goodsAllocation == null) {
			return AjaxResult.error("所选货位不存在");
		}

    	DeliveryRequest deliveryRequest = deliveryRequestMapper.findByBid(deliveryLogistics.getBidRequest());
    	if (!goodsAllocation.getWarehouseAddress().equals(deliveryRequest.getDestHouseAddress())) {
			return AjaxResult.error("所选货位不在目的地仓库");
		}
    	
    	if (deliveryLogistics.getStateName().equals(DeliveryLogisticsEnum.StateName.INIT.value)
    			|| deliveryLogistics.getStateName().equals(DeliveryLogisticsEnum.StateName.SUCCESS.value)) {
			return AjaxResult.error("该单据非已发货状态，无法操作");
		} else if (!deliveryLogistics.getStateRkName().equals(DeliveryLogisticsEnum.StateRkName.INIT.value)) {
			return AjaxResult.error("非未入库状态，无法操作");
		}
    	
    	// 更新货位
    	deliveryLogistics.setStateRkName(DeliveryLogisticsEnum.StateRkName.SUCCESS.value);
    	deliveryLogistics.setvHwTo(goodsAllocation.getGoodsAllocation());
    	deliveryLogistics.setvKqTo(goodsAllocation.getGoodsArea());

        
        // 添加库存相关
        List<StockControl> listStockControl = stockControlMapper.listByRkGuid(deliveryLogistics.getGuid());
        Date now = new Date();
    	for(StockControl stockControlOut : listStockControl) {
    		// 待入库总数量变更
    		Integer numAll = stockControlOut.getProductNumAll();
			stockControlOut.setProductNumAll(0);
			stockControlMapper.update(stockControlOut);
			


            // 添加库存-入库
    		StockControl stockControlIn = new StockControl();
    		{
    			stockControlIn.setGuid(RandomValueUtils.getGUID());
    			stockControlIn.setRkBid(deliveryLogistics.getBid());
    			stockControlIn.setRkGuid(deliveryLogistics.getGuid());
    			stockControlIn.setProductCode(stockControlOut.getProductCode());
    			stockControlIn.setProductName(stockControlOut.getProductName());
    			stockControlIn.setvHw(deliveryLogistics.getvHwTo());
    			stockControlIn.setvKq(deliveryLogistics.getvKqTo());
    			stockControlIn.setgDepot(deliveryLogistics.getDestHouseAddress());
    			stockControlIn.setvGsBm(deliveryLogistics.getvGsBm());
    			stockControlIn.setvGsMc(deliveryRequest.getvGsMc());
    			stockControlIn.setvGsJc(deliveryLogistics.getvGsJc());
    			stockControlIn.setProductNum(numAll);
    			stockControlIn.setProductNumAll(numAll);
    			stockControlIn.setdRkSj(now);
    			stockControlIn.setCreateTime(now);
    			stockControlIn.setIsParent(stockControlOut.getProductCode().contains("-") ? "0" : "1");
    			stockControlMapper.insert(stockControlIn);
    		}

			//根据仓库名称和商品编码查询箱规维护
			GaugeMaintenance gaugeMaintenance = gaugeMaintenanceMapper.getCodeAndWarehouseAddress(stockControlIn.getProductCode(), stockControlIn.getgDepot());
			//添加海外库存管理
			HwStorage hwStorage = new HwStorage();
			{
				hwStorage.setSku("C3426-" + stockControlIn.getProductCode());
				hwStorage.setCommoditycode(stockControlIn.getProductCode());
				hwStorage.setCommodityname(stockControlIn.getProductName());
				hwStorage.setBoxnum(stockControlIn.getProductNum() / gaugeMaintenance.getNum());
				hwStorage.setCartonsize(gaugeMaintenance.getLength() + "*" + gaugeMaintenance.getWeight() + "*" + gaugeMaintenance.getHeight());
				hwStorage.setSingleboxnum(gaugeMaintenance.getNum());
				hwStorage.setProductnum(stockControlIn.getProductNum());
				hwStorage.setProductnumall(stockControlIn.getProductNumAll());
				hwStorage.setSdays(stockControlIn.getsDays());
				hwStorage.setDrksj(stockControlIn.getdRkSj());
				hwStorage.setVhw(stockControlIn.getvHw());
				hwStorage.setVkq(stockControlIn.getvKq());
				hwStorage.setGdepot(stockControlIn.getgDepot());
				hwStorage.setVgsjc(stockControlIn.getvGsJc());
				hwStorage.setVgsbm(stockControlIn.getvGsBm());
				hwStorage.setCube((gaugeMaintenance.getLength().multiply(gaugeMaintenance.getWidth()).multiply(gaugeMaintenance.getHeight())).divide(new BigDecimal(1000000)).multiply(new BigDecimal(hwStorage.getBoxnum())));
				hwStorage.setStype(HwStorageEnum.StateName.HWCFH.value);
				hwStorage.setStatus(0);
				hwStorage.setCreatetime(now);
				hwStorage.setGuid(RandomValueUtils.getGUID());
				hwStorage.setKcId(stockControlIn.getGuid());
				hwStorage.setStorageCharge(BigDecimal.ZERO);
				hwStorage.setUnitPrice(BigDecimal.ZERO);
				hwStorageMapper.insert(hwStorage);
			}
    		
    		// 添加库存流水-入库
    		{
    		StockControlRunning stockControlRunning = new StockControlRunning();
        		stockControlRunning.setGuid(RandomValueUtils.getGUID());
        		stockControlRunning.setGuidStockControl(stockControlIn.getGuid());
        		stockControlRunning.setBidRelative(bid);
        		stockControlRunning.setLocationHw(stockControlIn.getvHw());
        		stockControlRunning.setProductCode(stockControlIn.getProductCode());
        		stockControlRunning.setvGsBm(stockControlIn.getvGsBm());
        		stockControlRunning.setProductNumChange(numAll);
        		stockControlRunning.setProductNumLeft(stockControlIn.getProductNum());
        		stockControlRunning.setCreateTime(now);
        		
        		stockControlRunning.setRemark("海外仓入库" + bid);
        		stockControlRunningMapper.insert(stockControlRunning);
    		}
        }

		//判断是否需要登录
		if (redisUtil.get("FROESTLOGIN") == null){
			JSONObject jsonObject = FroestHttPUtils.froestLogin();
			if (jsonObject.get("code") != null){
				if (!jsonObject.get("code").equals("200")){
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return AjaxResult.error("连接大森林海外仓API失败,请联系管理员处理!");
				}
			}
			redisUtil.setEx("FROESTLOGIN", jsonObject.get("access_token").toString(),Long.valueOf(jsonObject.get("expires_in").toString()),TimeUnit.SECONDS);
			redisUtil.setEx("FROESTLOGINCode", jsonObject.get("customerCode").toString(),Long.valueOf(jsonObject.get("expires_in").toString()),TimeUnit.SECONDS);
		}

		//入库单查询
		JSONObject jsonObject = FroestHttPUtils.froestApiRequest("",redisUtil.get("FROESTLOGIN"),
				ApiConfig.getWmsUrl()+"/interface/wmsOrderApi/queryGodwnEntryOrderDetatil?godownEntryNo="+deliveryLogistics.getOverseasStockInNo());
		if (jsonObject.get("code") != null){
			if (!jsonObject.get("code").equals(200)){
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				logger.error("大森林海外仓API入库单详情失败，错误为：" + jsonObject.get("message"));
				return AjaxResult.error("大森林海外仓API入库单详情失败,请联系管理员处理!");
			}
		}
		JSONObject result = JSONObject.parseObject(jsonObject.get("result").toString());
		//已上架
		if (result.get("status").toString().equals("4")){
			deliveryLogistics.setTimeArrivePredict(result.get("takeDeliveryOfGoodsFirstTime").toString());
			JSONArray skuList = JSONObject.parseArray(result.get("skuList").toString());
			//查询发货物流明细
			List<DeliveryLogisticsDetail> deliveryLogisticsDetails = deliveryLogisticsDetailMapper.listByBidLogistics(deliveryLogistics.getBid());
			for(DeliveryLogisticsDetail deliveryLogisticsDetail : deliveryLogisticsDetails) {
				for (int i = 0; i <skuList.size(); i++) {
					JSONObject jsonObject1 =  JSONObject.parseObject(skuList.get(i).toString());
					if (deliveryLogisticsDetail.getBoxNo() == Integer.valueOf(jsonObject1.get("no").toString())){
						deliveryLogisticsDetail.setProductSjNum(Integer.valueOf(jsonObject1.get("realDeliveryNum").toString()));
						deliveryLogisticsDetailMapper.update(deliveryLogisticsDetail);
					}
				}
			}
			deliveryLogistics.setRkTime(now);
			deliveryLogisticsMapper.update(deliveryLogistics);
		}else {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			logger.error("大森林海外仓API入库单未入库");
		}

        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }
	
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult stockInBack(String bid) throws Exception {
    	
    	DeliveryLogistics deliveryLogistics = deliveryLogisticsMapper.findByBid(bid);
    	if (!deliveryLogistics.getStateName().equals(DeliveryLogisticsEnum.StateName.SUCCESS.value)) {
			return AjaxResult.error("该单据非已审核状态，无法重复操作");
		} else if (!deliveryLogistics.getStateRkName().equals(DeliveryLogisticsEnum.StateRkName.INIT.value)) {
			return AjaxResult.error("非未入库状态，无法操作");
		}
        
        // 添加库存相关-清除待入库数据
        List<StockControl> listStockControl = stockControlMapper.listByRkGuid(deliveryLogistics.getGuid());
    	for(StockControl stockControl : listStockControl) {
        	stockControlMapper.deleteStockControl(stockControl.getGuid());
        }
    	
    	// 原库存总数量退回
    	List<DeliveryRequestDetail> listDeliveryRequestDetail = deliveryRequestDetailMapper.queryFirstByPBid(deliveryLogistics.getBidRequest());
        // 商品-总数量MAP，商品-商品名称MAP，用于待入库区
    	for(DeliveryRequestDetail deliveryRequestDetail : listDeliveryRequestDetail) {
    		// 解冻出库
    		StockControl stockControlOut = stockControlMapper.findByGuid(deliveryRequestDetail.getGuidKc());
    		{
    			stockControlOut.setProductNumAll(stockControlOut.getProductNumAll() + deliveryRequestDetail.getNumDeliver());
    			stockControlMapper.update(stockControlOut);
    		}
        }

		//从逸思精品账户（公司账户）向物流部账户（部门账户）进行划拨。
		SysAccountBandDept wlb = sysAccountBandDeptMapper.findByAccountId("WLB");
		if (wlb == null) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return AjaxResult.error("物流部(部门账户)不存在,请核实后再操作!");
		}
		// 物流公司
		AccountCountForCompany logisticsAccount = accountCountForCompanyMapper.queryFirstByVGsBm(wlb.getvGsBm());
		if (logisticsAccount == null) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return AjaxResult.error("物流公司实时资金不存在,请核实后再操作!");
		}
//                     精品公司
		AccountCountForCompany jpAccount = accountCountForCompanyMapper.queryFirstByVGsBm(deliveryLogistics.getvGsBm());
		if (jpAccount == null) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return AjaxResult.error("逸思精品实时资金不存在,请核实后再操作!");
		}
		List<AccountDetailedForCompany> accountList =new ArrayList<>();
		AccountDetailedForCompany account = new AccountDetailedForCompany();
		account.setGuid(RandomValueUtils.getGUID());
		account.setvGsBm(jpAccount.getvGsBm());
		account.setvGsMc(jpAccount.getvGsMc());
		account.setvGsJc(jpAccount.getvGsJc());
		account.setvGsBmP(logisticsAccount.getvGsBm());
		account.setvGsMcP(logisticsAccount.getvGsMc());
		account.setvGsJcP(logisticsAccount.getvGsJc());
		account.setvJyLx("物流服务→头程运费");
		account.setfJe(Double.valueOf(String.valueOf(deliveryLogistics.getPriceTotal())));
		account.setdJySj(deliveryLogistics.getCreateTime());
		account.setdShSj(new Date());
		account.setvBz("(回退)头程物流费," + "海外发货申请单:"+deliveryLogistics.getBidRequest()+",物流方式名称:"+deliveryLogistics.getNameLogsticsWay());
		account.setCreateTime(new Date());
		accountList.add(account);

		//资金流水(物流部 -运营公司头程物流费)
		AccountDetailedForCompany account1 = new AccountDetailedForCompany();
		account1.setGuid(RandomValueUtils.getGUID());
		account1.setvGsBm(logisticsAccount.getvGsBm());
		account1.setvGsMc(logisticsAccount.getvGsMc());
		account1.setvGsJc(logisticsAccount.getvGsJc());
		account1.setvGsBmP(jpAccount.getvGsBm());
		account1.setvGsMcP(jpAccount.getvGsMc());
		account1.setvGsJcP(jpAccount.getvGsJc());
		account1.setvJyLx("物流服务→头程运费");
		account1.setfJe(-Double.valueOf(String.valueOf(deliveryLogistics.getPriceTotal())));
		account1.setdJySj(deliveryLogistics.getCreateTime());
		account1.setdShSj(new Date());
		account1.setvBz("(回退)头程物流费,"+ "海外发货申请单:"+deliveryLogistics.getBidRequest()+",物流方式名称:"+deliveryLogistics.getNameLogsticsWay());
		account1.setCreateTime(new Date());
		accountList.add(account1);

		if (accountList.size() != 0){
			businessMapper.insertBatchNew(accountList);
		}

		//判断是否需要登录
		if (redisUtil.get("FROESTLOGIN") == null){
			JSONObject jsonObject = FroestHttPUtils.froestLogin();
			if (jsonObject.get("code") != null){
				if (!jsonObject.get("code").equals("200")){
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return AjaxResult.error("连接大森林海外仓API失败,请联系管理员处理!");
				}
			}
			redisUtil.setEx("FROESTLOGIN", jsonObject.get("access_token").toString(),Long.valueOf(jsonObject.get("expires_in").toString()),TimeUnit.SECONDS);
			redisUtil.setEx("FROESTLOGINCode", jsonObject.get("customerCode").toString(),Long.valueOf(jsonObject.get("expires_in").toString()),TimeUnit.SECONDS);
		}

		//入库单审核
		JSONObject jsonObject = FroestHttPUtils.froestApiRequest("",redisUtil.get("FROESTLOGIN"),
				ApiConfig.getWmsUrl()+"/interface/wmsOrderApi/cancelGodwnEntryOrder?godownEntryNo="+deliveryLogistics.getOverseasStockInNo());
		if (jsonObject.get("code") != null){
			if (!jsonObject.get("code").equals(200)){
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				logger.error("大森林海外仓API入库单审核失败，错误为：" + jsonObject.get("message"));
				return AjaxResult.error("大森林海外仓API入库单审核失败,请联系管理员处理!");
			}
		}

		deliveryLogisticsMapper.updateStateAndOverseasStockInNo(bid,   DeliveryLogisticsEnum.StateName.INIT.value, null);
    	
        
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }
	
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult editWayBillNumber(String bid, String wayBillNumber) throws Exception {
    	
    	if (wayBillNumber == null || wayBillNumber.length() == 0) {
			return AjaxResult.error("运单号不能为空");
		} else if (wayBillNumber.length() > 30) {
			return AjaxResult.error("运单号长度不能超过30");
		}
    	
    	DeliveryLogistics deliveryLogistics = deliveryLogisticsMapper.findByBid(bid);
    	if (deliveryLogistics == null) {
			return AjaxResult.error("物流订单不存在");
		}
    	if (!deliveryLogistics.getStateName().equals(DeliveryLogisticsEnum.StateName.SUCCESS.value)) {
			return AjaxResult.error("该单据非已审核状态，无法修改运单号");
		}
    	
        deliveryLogisticsMapper.updateWayBillNumber(bid, wayBillNumber, DeliveryLogisticsEnum.StateName.SENDED.value);
        
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }
	
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult editTimeArrivePredict(String bid, String timeArrivePredict) throws Exception {
    	
    	if (timeArrivePredict == null || timeArrivePredict.length() == 0) {
			return AjaxResult.error("日期不能为空");
		}
    	
    	DeliveryLogistics deliveryLogistics = deliveryLogisticsMapper.findByBid(bid);
    	if (deliveryLogistics == null) {
			return AjaxResult.error("物流订单不存在");
		}
    	if (deliveryLogistics.getStateRkName().equals(DeliveryLogisticsEnum.StateRkName.SUCCESS.value)) {
			return AjaxResult.error("该单据已入库，无法修改预计入库时间");
		}
    	
        deliveryLogisticsMapper.updateTimeArrivePredict(bid, timeArrivePredict);
        
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }
}
